package com.edee.bigday.seckill.scheduled;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * 1、@EnableScheduling开启定时任务功能
 * 2、@Component放入容器
 * 3、@Scheduled(cron = "")创建一个定时任务
 */
@Slf4j
@Component
//@EnableScheduling
//@EnableAsync //开启异步任务功能
public class HelloSchedule {
//    @Autowired
//    ThreadPoolExecutor executor;
    /**
     * Spring中的Scheduled和Quartz的区别：
     * 1、Spring中，cron表达式的时间有6个时间单位组成，不支持第7位“年”。异常如下：
     * nested exception is java.lang.IllegalStateException: Encountered invalid @Scheduled method 'hello': Cron expression must consist of 6 fields (found 7 in "......")
     * 2、Spring中，在周的位置，周一-周日分别对应1-7，而Quartz中对应2,3,4,5,6,7,1。二者都可以使用MON-SUN表示。
     * 3、定时任务不应该阻塞，而SpringBoot中的定时任务默认是阻塞的。解决办法有：
     *      3.1）SpringBoot中可以让业务以异步方式提交到线程池：
     *          CompletableFuture.runAsync(() -> {
     *             log.info("hello,scheduled...");
     *             try {
     *                 Thread.sleep(3000);
     *             } catch (InterruptedException e) {
     *                 e.printStackTrace();
     *             }
     *         }, executor);
     *     3.2）SpringBoot支持定时任务线程池，在TaskSchedulingAutoConfiguration.java中，有@EnableConfigurationProperties(TaskSchedulingProperties.class)，
     *         进入TaskSchedulingProperties，发现：
     * 		        Maximum allowed number of threads.
     * 		        private int size = 1; //说明线程池只有一个线程。
     *	        在application.properties:7中设置定时任务线程池容量：
     * 		        #设置定时任务线程池容量（有时不生效）
     *               spring.task.scheduling.pool.size=5
     *       3.3）让定时任务异步执行。SpringBoot异步任务。
     *               @EnableAsync //开启异步任务功能(标注在类上)
     *               @Async  //标在方法上。
     *       3.4）异步任务的自动配置类为：TaskExecutionAutoConfiguration，属性绑定在TaskExecutionProperties。
     *               在TaskExecutionProperties中：
     *               private int coreSize = 8;
     *               private int maxSize = Integer.MAX_VALUE;
     *       3.5）使用异步任务和定时任务，保证定时任务不阻塞。
     *
     **/
    @Async
//    @Scheduled(cron = "*/2 * * ? * 3")
    public void hello() throws InterruptedException {
//        CompletableFuture.runAsync(() -> {
            log.info("hello,scheduled...");
//            try {
                Thread.sleep(3000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }, executor);
    }
}
